﻿#NoEnv
#HotkeyInterval 2000
#MaxHotkeysPerInterval 800
SendMode Input
SetKeyDelay,30,0
SetWorkingDir %A_ScriptDir%
#SingleInstance
#SingleInstance,Force
#InstallKeybdHook
#InstallMouseHook
#KeyHistory
#Include Class_OD_Colors.ahk
#Include Class_WinClipAPI.ahk
#Include Class_WinClip.ahk
#Include Class_EasyIni.ahk
#Include Class_ImageButton.ahk
CoordMode, Caret, Screen
OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x200, "WM_MOUSEMOVE")
WinGetPos,,,,Shell_Wnd ,ahk_class Shell_TrayWnd
Menu, TRAY, NoStandard
Menu, TRAY, DeleteAll

if !FileExist(A_AppData "\RimeToolData\CnCode")
	FileCreateDir,%A_AppData%\RimeToolData\CnCode
marks:="""",full_command_line := RegExReplace(DllCall("GetCommandLine", "str"),marks)
If !A_IsAdmin {
	If A_IsCompiled {
		Run *RunAs "%full_command_line%" /restart,,UseErrorLevel
		if A_LastError
			MsgBox, 262160, 运行错误, 运行权限不足，请以管理员身份运行！,10
		ExitApp
	}else{
		Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%",,UseErrorLevel

	}
}

DefaultData:={Settings:{FontName:"98WB-3",init:0,AutoScroll:1,SleepTime:50
	,Schema:98,PasteType:0,SchemaList:"86|98|06",FontSize:16,Isbold:0,ToNext:1
	,IsContinue:1,IsCopy:1,GuiBgColor:"4285f4",Hotkeys:"LAlt",IsAutoSave:1}}
PhraseIni:=class_EasyIni(A_AppData "\RimeToolData\CnCode\helper.ini")
For Section, element In DefaultData
	For key, value In element
		If ((%key%:=PhraseIni[Section, key])="")
			%key%:=PhraseIni[Section, key]:=value
PhraseIni.save(),versions:="1.70"

FileDelete,%A_AppData%\RimeToolData\debug.Log

Menu, Tray, UseErrorLevel
Menu, TRAY,Add, 关于,Onabout
Menu, TRAY,Add,
Menu, TRAY,Add, 资源库,OnHelp
Menu, Item,Add, 重置程序参数,RestartAll
Menu, SleepTime,Add, 25,SetSleepTime
Menu, SleepTime,Add, 50,SetSleepTime
Menu, SleepTime,Add, 100,SetSleepTime
Menu, SleepTime,Add, 150,SetSleepTime
Menu, SleepTime,Add, 200,SetSleepTime
Menu, SleepTime,Add, 250,SetSleepTime
Menu, SleepTime,Add, 300,SetSleepTime
Menu, SleepTime,Check,%SleepTime%
Menu, Item,Add,
Menu, Item,Add, 延迟时间(ms),:SleepTime
Menu, Item,Add,
Menu, Item,Add, 强制获取光标行,IsCopy
if IsCopy
	Menu, Item,Check,强制获取光标行
Menu, Item,Add,
Menu, Item,Add, 连续处理下一行,IsContinue
if IsContinue
	Menu, Item,Check,连续处理下一行
Menu, Item,Add,
Menu, Item,Add, 上屏后自动保存,SaveAll
if IsAutoSave
	Menu, Item,Check,上屏后自动保存
Menu, Item,Add,
Menu, Item,Add, 上屏后自动滚屏,SetAutoScroll
if AutoScroll
	Menu, Item,Check,上屏后自动滚屏
Menu, Item,Add,
Menu, Item,Add, 自动跳过已拆分行,SetToNextLine
if ToNext
	Menu, Item,Check,自动跳过已拆分行
Menu, TRAY,Add,
Menu, Tray,Add, 参数设置,:Item
Menu, TRAY,Add,
Menu, Tray,Add, 单字提取,GetFullCode
Menu, TRAY,Add,
Menu, Tray,Add, 单字匹配,SetFullCode
Menu, TRAY,Add,
Menu, TRAY,Add, 重启程序,OnReload
Menu, TRAY,Add,
Menu, TRAY,Add, 退出程序,OnExit
Menu, TRAY,Tip, 拆分扩编助手v%versions%`n - 码表格式：单字+Tab+编码`n - 格式符合要求才会触发选择框`n - 触发键：%Hotkeys%
Menu, TRAY,Color,ffffff

PhraseObj:={86:{a:"󰂆||󰂇|||󰂈|󰂉|󰁺||||󰂊|󰂋|||󰂌|"
	,s:"󰄅||󰄉|󰄆|󰄇|󰄈"
	,d:"󰂝||󰂣|󰂞|󰂜|||󰂟|󰂠|󰂡|𠂇|󰂢||󰀌"
	,f:"󰂮|||󰂯|󰂭|󰂰|󰂱|󰀜|󰀛|󰂳|󰂲|󰀙|󰀘"
	,g:"󰂷||󰁽|龶||󰂸|󰀞|󰂶|󰀝"
	,h:"󰂼||󰀣|󰂽|󰀥|󰂾|󰁾|󰂿|||󰂺|󰂻|󰀢"
	,j:"󰃊||󰃋|󰀰||󰀱|󰃌|󰀭|󰀮|󰀯|󰃉|󰀮|󰃍|󰀬"
	,k:"󰃏||󰃎|󰀶|󰀵"
	,l:"󰃐||󰃑|󰃒|󰃓|󰃔|󰀹|󰀺|󰀷|󰃕|󰃖||󰂫"
	,m:"󰃘||󰃙|󰃚|󰃜|󰀼|󰀽|󰀿|󰄨|󰁰|󰀾"
	,q:"󰃴||󰃶|󰃺|󰁜|󰃷||󰄄||󰀸|󰁢|󰁝|󰃹|󰃸|||󰁚"
	,w:"󰄤||󰄥|󰄦|󰄧|"
	,e:"󰂧||󰀐||󰀑|󰂖|󰂨||󰀒|󰀓||󰀔|󰀕|󰀖|󰂥|󰂦||󰀏"
	,r:"󰃽||󰃾|󰃿|||龵|󰄀||||󰃼|󰁣"
	,t:"󰄌||||󰄍|󰄋|󰁿|󰄎|󰄏|󰄐|𠂉||󰄎|󰁥"
	,y:"󰄳||󰄴|󰄵|󰄷|󰄸|󰁸|󰄶|󰃫|󰁷|󰄲|󰄼|󰁶"
	,u:"󰄓|||󰄔|󰄕|󰄒|󰁦|󰄑|󰁨|󰁩|󰄿|󰄘|󰄙|󰄛|󰁧"
	,i:"󰃂||󰃁|󰀧||󰃃|󰃅|||󰃆|||󰀪|󰀤||󰀦"
	,o:"󰃩||󰃪|||󰁗|󰁖|󰃨"
	,p:"󰃭||󰃮|󰃯||󰃰|󰃱|"
	,n:"󰃞||󰃟|󰃠|󰁃|󰁄|󰃢|󰃥|󰁅|󰁁|󰁂|󰃡|󰃣|󰃤|󰁇|󰁈|󰁉|󰁊|󰁋|󰁌|󰁍|󰁎|󰁏|󰁐|󰁒|󰁓|󰁔|󰁕|󰂁|󰂂|󰂄|󰃝|󰃦|󰄃|󰄺|󰄻|󰁑|󰁀"
	,b:"󰂍||󰂎|󰂐|󰂏|󰀇|󰂑|󰁹|󰀈|󰂒|󰂓|󰂔|󰄽|󰀅"
	,v:"󰄟||󰄠|󰄡|󰂪|󰁬|󰁭|󰄢|󰄞|󰁫"
	,c:"󰂘||󰂚||󰂙|󰀉|󰁻"
	,x:"||󰄬|󰄮|󰁳|󰁴||󰁲|󰄩|󰄪"}

	,98:{a:"󰂆||󰀁|󰂇|󰂉|󰅬|󰅅|󰅓|󰅚|󰁺|󰂈|󰂊|󰄖|󰀀|󰀂|󰀄|󰂋|󰅙|󰀃|󰂌"
	,s:"󰄅||󰄆|󰄇|󰄈|󰄉|󰄊|󰅣"
	,d:"󰂝||󰂢|󰁼|󰂜|󰀍|󰂞|󰂣|󰂤|󰀎|󰂟|󰂠|󰂡|󰀌"
	,f:"󰂮||󰂯|󰂭|󰂰|󰂵|󰂱|󰀛|󰂳|󰂴|󰀜|󰀚|󰀙|󰂲|󰀘"
	,g:"󰂷||󰁽|󰂸|󰀟|󰀠|󰂹|󰅜|󰂅|󰀡|󰂶|󰀞|󰀝"
	,h:"󰂼||󰀣|󰀥|󰁾|󰂽|󰂾|󰂿|󰀤|󰃀|󰂺|󰂻|󰀢"
	,j:"󰃊||󰀰|󰀱|󰃋|󰃌|󰃍|󰀯|󰃉|󰀮|󰀭|󰀳|󰀲|󰀬"
	,k:"󰃏||󰀸|󰃎|󰀶|󰀵"
	,l:"󰃐||󰃑|󰃒|󰃓|󰀹|󰀺|󰀻|󰃔|󰃕|󰀷|󰃖|󰃗"
	,m:"󰃘||󰃙|󰃚|󰃛|󰀼|󰀽|󰀿|󰃜|󰀾|󰅏|󰅐|󰅑"
	,q:"󰃴||󰃵|󰃶|󰃷|󰃸|󰃹|󰁡|󰃻|󰁚|󰁛|󰁝|󰁜|󰃺|󰁞|󰁟|󰁠|󰁢"
	,w:"󰄤||󰄥|󰄦|󰁰|󰄨|󰁯|󰄧|󰅄|󰅈|󰅉|󰅮|󰅰|󰁱|󰅁"
	,e:"󰂧||󰅘|󰂥|󰀔|󰀕|󰀖|󰂬|󰂫|󰀐|󰀑|󰅗|󰀒|󰂨|󰅎|󰅆|󰂦|󰂩|󰀓|󰅝|󰀗|󰂪|󰀏"
	,r:"󰃽||󰃾|󰃿|󰂀|󰄂|󰄄|󰁤|󰃼|󰄀|󰄁|󰁣"
	,t:"󰄌||󰄍|󰄋|󰁿|󰄎|󰄐|󰄏|󰁥"
	,y:"󰄳||󰄴|󰄵|󰄷|󰄸|󰁸|󰄶|󰂃|󰄲|󰄼|󰁷|󰄹|󰅍|󰀴|󰁶"
	,u:"󰄓||󰄔|󰁨|󰄒|󰄑|󰁦|󰄕|󰁩|󰄗|󰄿|󰄘|󰄛|󰄙|󰁪|󰅛|󰄜|󰄝|󰄚|󰅌|󰁧"
	,i:"󰃁||󰃂|󰀨|󰀪|󰃈|󰅯|󰀩|󰃃|󰃄|󰃆|󰀫|󰅪|󰅫|󰅇|󰅊|󰃅|󰀧|󰃇|󰀦"
	,o:"󰃩||󰁖|󰁗|󰃬|󰃪|󰃫|󰃨|󰁙|󰁘"
	,p:"󰃮||󰃭|󰅂|󰃯|󰃰|󰃱|󰃲|󰃳"
	,n:"󰁁||󰃞|󰃟|󰃠|󰃢|󰁅|󰃧|󰁂|󰃡|󰅭|󰃣|󰃤|󰃥|󰅋|󰁃|󰁄|󰁔|󰂁|󰄺|󰄻|󰁆|󰁇|󰁈|󰁉|󰁊|󰁋|󰁌|󰁍|󰁎|󰁏|󰁐|󰁒|󰁓|󰁕|󰂂|󰂄|󰃝|󰃦|󰄃|󰁑|󰅕|󰅖|󰁀"
	,b:"󰂍||󰂎|󰂏|󰂒|󰀆|󰂖|󰂗|󰀇|󰂑|󰁹|󰂓|󰂔|󰀈|󰂕|󰂐|󰄽|󰀅"
	,v:"󰄡||󰄟|󰄠|󰄞|󰅔|󰁬|󰁭|󰄢|󰄣|󰁮|󰅃|󰅞|󰅟|󰁫"
	,c:"󰂘||󰂙|󰂛|󰂚|󰀉|󰁻|󰀊|󰀋|󰅒"
	,x:"󰁲||󰄩|󰄪|󰄫|󰅀|󰁴|󰄮|󰁳|󰄭|󰄯|󰄰|󰄬|󰁵|󰄱|󰅢|󰅤|󰅥|󰅦|󰅧|󰅨|󰅩"
	,d1:"󰂝||󰂢|󰀌|󰁼|󰂜|󰀍|󰂞|󰂣|󰂤|󰀎|󰂟|󰂠|󰂡"
	,f1:"󰂮||󰂯|󰀘|󰂭|󰂰|󰂵|󰂱|󰀛|󰂳|󰂴|󰀜|󰀚|󰀙|󰂲"
	,g1:"󰂷||󰁽|󰀝|󰂸|󰀟|󰀠|󰂹|󰅜|󰂅|󰀡|󰂶|󰀞"
	,h1:"󰂼||󰀣|󰀢|󰀥|󰁾|󰂽|󰂾|󰂿|󰀤|󰃀|󰂺|󰂻"
	,j1:"󰃊||󰀰|󰀬|󰀱|󰃋|󰃌|󰃍|󰀯|󰃉|󰀮|󰀭|󰀳|󰀲"
	,k1:"󰃏||󰀸|󰀵|󰃎|󰀶"
	,e1:"󰂧||󰅘|󰀏|󰂥|󰀔|󰀕|󰀖|󰂬|󰂫|󰀐|󰀑|󰅗|󰀒|󰂨|󰅎|󰅆|󰂦|󰂩|󰀓|󰅝|󰀗|󰂪"
	,r1:"󰃽||󰃾|󰁣|󰃿|󰂀|󰄂|󰄄|󰁤|󰃼|󰄀|󰄁"
	,t1:"󰄌||󰄍|󰁥|󰄋|󰁿|󰄎|󰄐|󰄏"
	,y1:"󰄳||󰄴|󰁶|󰄵|󰄷|󰄸|󰁸|󰄶|󰂃|󰄲|󰄼|󰁷|󰄹|󰅍|󰀴"
	,u1:"󰄓||󰄔|󰁧|󰁨|󰄒|󰄑|󰁦|󰄕|󰁩|󰄗|󰄿|󰄘|󰄛|󰄙|󰁪|󰅛|󰄜|󰄝|󰄚|󰅌"
	,i1:"󰃁||󰃂|󰀦|󰀨|󰀪|󰃈|󰅯|󰀩|󰃃|󰃄|󰃆|󰀫|󰅪|󰅫|󰅇|󰅊|󰃅|󰀧|󰃇"
	,n1:"󰁁||󰃞|󰁀|󰃟|󰃠|󰃢|󰁅|󰃧|󰁂|󰃡|󰅭|󰃣|󰃤|󰃥|󰅋|󰁃|󰁄|󰁔|󰂁|󰄺|󰄻|󰁆|󰁇|󰁈|󰁉|󰁊|󰁋|󰁌|󰁍|󰁎|󰁏|󰁐|󰁒|󰁓|󰁕|󰂂|󰂄|󰃝|󰃦|󰄃|󰁑|󰅕|󰅖"
	,b1:"󰂍||󰂎|󰀅|󰂏|󰂒|󰀆|󰂖|󰂗|󰀇|󰂑|󰁹|󰂓|󰂔|󰀈|󰂕|󰂐|󰄽"
	,v1:"󰄡||󰄟|󰁫|󰄠|󰄞|󰅔|󰁬|󰁭|󰄢|󰄣|󰁮|󰅃|󰅞|󰅟"}

	,06:{a:"󰂆||󰀁|󰂇|󰂉|󰁺|󰂈|󰂊|󰄖|󰀀|󰀂|󰀄|󰂋|󰀃|󰂌"
	,s:"󰄅||󰄆|󰄇|󰄈|󰄉"
	,d:"󰂝||󰂢|󰁼|󰂜|󰀍|󰂟|󰂠|󰂡|󰀌"
	,f:"󰂮||󰂯|󰂭|󰂰|󰂱|󰀛|󰂳|󰂴|󰀙|󰂲|󰀘"
	,g:"󰂷||󰁽|󰂸|󰀟|󰀠|󰂶|󰀞|󰀝"

	,h:"󰂼||󰀣|󰀥|󰁾|󰂾|󰂿|󰀤|󰁾||󰂺|󰂻|󰀢"
	,j:"󰀰||󰃊|󰃋||󰃍|󰀯|󰀮|󰀭|󰃉|󰀬"
	,k:"󰀸||󰃎|󰃏|󰀶|󰀵"
	,l:"󰃐||󰃑|󰃒|󰃓|󰀹|󰀺|󰃔|󰃕||󰀷||󰃖|󰀻|󰃗"
	,m:"󰀼||󰃘|󰀽|󰀾|󰀿|󰃙|󰃚|󰃛|󰃜"

	,q:"󰃴||󰃶|󰃻|󰁚|󰁛|󰁜|󰁝|󰁡|󰁢|󰃷|󰃸|󰃹|󰃵|󰃺"
	,w:"󰄤||󰄦|󰁯|󰁰|󰄨|󰄥|󰄧|󰁱"
	,e:"󰂦||󰂩|󰀓|󰂥|󰀔|󰀕|󰂧|󰀗|󰂪|󰀖|󰂫|󰀐|󰀑|󰁪|󰀏"
	,r:"󰄄||󰁤|󰃼|󰄀||󰃽||󰂀|󰃾|󰃿|󰁣"
	,t:"󰄌||||󰄍|󰄎|󰄐|󰁿|󰄏||󰄋|󰂛|󰁥"

	,y:"󰄳||󰄴|󰄵|󰄸|󰁷|󰄶|󰄷|󰂃|󰄲|󰄼|󰁶"
	,u:"󰄓||󰄘|󰄛|󰁨|󰄒|󰄕|󰄙|󰄑|󰄿|󰁩|󰁦|󰁧"
	,i:"󰃁||󰀨|󰀪|󰀧|󰃈|󰀩|󰃃|󰃄|󰃆|󰀫|󰃅||󰃂|󰀦"
	,o:"󰃩||󰃪|󰃫|󰃨|󰁘|󰁖|󰁗|"
	,p:"󰃮||󰃭||󰃲|󰃰|󰃳|󰃯|󰃱"

	,n:"󰁁||󰁂|󰁃|󰁄|󰃞|󰃟|󰃠|󰃡|󰃢|󰃥|󰁅|󰃣|󰃤|󰁆|󰁇|󰁈|󰁉|󰁊|󰁋|󰁌|󰁍|󰁎|󰁏|󰁐|󰁒|󰁓|󰁔|󰁕|󰂁|󰂂|󰂄|󰃝|󰃦|󰄃|󰄺|󰄻|󰁑|󰁀"
	,b:"󰂍||󰂎|󰂏|󰂒|󰂖|󰀇|󰂑|󰀆|󰁹|󰂓|󰂔|󰀈|󰂕|󰂐|󰄽|󰀅"
	,v:"󰄡||󰄟|󰄠|󰄞|󰁬|󰁭|󰄢|󰁫"
	,c:"󰂘||󰂙|󰀊|󰀋|󰂚|󰀉|󰁻|"
	,x:"󰁲||󰄩|󰄪|󰄭||󰁴|󰄮|󰁳||󰄬|󰁵|󰄱"}}

FileInstall,UnionRadicalFont.otf,%A_AppData%\RimeToolData\CnCode\UnionRadicalFont.otf,1
FileInstall,98WB-3.otf,%A_AppData%\RimeToolData\CnCode\98WB-3.otf,1
Gosub InstallFont

IsPaste:=0,Height_Pos:=0,Height_Pos:=0,CustomMaBiao:={},BreakItem:=0
SchemaList:=RegExReplace(SchemaList,"^\||\|$"),DefaultFontName:=GetDefaultFontName()
if A_IsCompiled
	EtymologyTable:=RegExReplace(A_ScriptName,"\.exe$",".txt")
Else
	EtymologyTable:=RegExReplace(A_ScriptFullPath,"\.ahk$",".txt")
if !init {
	MsgBox, 262144,拆分助手, 工具操作说明：`n- 仅支持识别单行单义码表「单字+Tab+编码」，`n- 光标置于目标行上或者目标行内容，`n- 按LAlt键弹出选取框，`n- 操作完成再按LAlt上屏。`n自定义拆分码元格式：`n- [a-z]+Tab+键位所有拆分码元`n- 自定义拆分码元文件与启动文件同名。,10
	PhraseIni.Settings["init"]:=1,PhraseIni.save()
}

kbhk := 0, mhk := 0
KBCallback := RegisterCallback("KeyboardHookProc",,3)
MCallback := RegisterCallback("MouseHookProc",,3)
Hotkey,$%Hotkeys%,SendClipText,on
Hotkey,WheelUp,WheelUpSetting,on
Hotkey,WheelDown,WheelDownSetting,on
ShowGui:
	CFID:=WinActive("A")
	debug("`n*********窗口重绘*********`n当前活动窗口句柄：" CFID "`n当前码元方案：" Schema "`n组合结果另起一行上屏：" (PasteType?"开启":"关闭") "`n自动滚屏：" (AutoScroll?"开启":"关闭") "`n连续处理：" (IsContinue?"开启":"关闭") "`n强行获取光标文字：" (IsCopy?"开启":"关闭") "`n上屏触发键：" Hotkeys "`n自动保存：" (IsAutoSave?"开启":"关闭") "`n跳过已处理行：" (ToNext?"开启":"关闭") "`n显示字体为：" FontName )
	Gui,Phrase:Destroy
	Gui,Phrase:-Caption +AlwaysOnTop +LastFound +Owner -DPIScale HWNDMakePhrase  ;-MinimizeBox -MaximizeBox 
	Gui,Phrase:margin,15,25
	Gui,Phrase:Color,% (GuiBgColor~="i)0x"?SubStr(GuiBgColor,2):GuiBgColor),% (GuiBgColor~="i)0x"?SubStr(GuiBgColor,2):GuiBgColor)
	Gui,Phrase:Font,s15 bold,%DefaultFontName%
	Gui,Phrase:Add,Text,x+0 y+20 vbianma Center cffffff,[ UUUU ]
	GuiControlGet,tpos,Phrase:pos,bianma
	;;Gui Phrase:Add, Text,% "xm y" tposY+tposH+5 " w" tposW " h2 0x10"
	Gui,Phrase:Font,s44 norm,%FontName%
	Gui,Phrase:Add,Text,xm+15 y+30 Center gChangeColor vtip cffffff,囗
	GuiControlGet,pos,Phrase:pos,tip
	Gui,Phrase:Font,% "s" FontSize (Isbold?" bold":" norm"),%FontName%
	Gui Phrase:Add, Text,% "x" posX+tposW " ym-100 h150 h2 0x11 vnext_part_line "
	OD_Colors.SetItemHeight("s" FontSize*1.1 " cffffff " (Isbold?"bold":"norm"), FontName)
	Gui,Phrase:Add,ddl,% "x" posX+tposW+25 " ym+5 w85 cwhite gControl_set vpart_1 hwndHDDL1 +0x0210",
	OD_Colors.Attach(HDDL1,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
	Gui,Phrase:Add,ddl,x+15 gControl_set yp w85 vpart_2 hwndHDDL2 +0x0210,
	OD_Colors.Attach(HDDL2,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
	Gui,Phrase:Add,ddl,x+15 gControl_set yp w85 vpart_3 hwndHDDL3 +0x0210,
	OD_Colors.Attach(HDDL3,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
	Gui,Phrase:Add,ddl,x+15 gControl_set yp w85 vpart_4 hwndHDDL4 +0x0210,
	OD_Colors.Attach(HDDL4,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
	Gui,Phrase:Font,s10 norm,%DefaultFontName%
	OD_Colors.SetItemHeight("s15 cffffff norm", DefaultFontName)
	GuiControlGet,pos,Phrase:pos,part_1
	Gui,Phrase:Add,ddl,% "x" posX " y" posY+posH+15 " gControl_set w125 vpart_5 hwndHDDL5 +0x0210 Center" ,%SchemaList%
	GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
	OD_Colors.Attach(HDDL5,{T: 0xFFFFFF, B: Schema=="86"?"0x4285f4":Schema=="98"?"0x665cdd":Schema=="6"?"0x15c23c":"0xcc4f20"})
	Gui,Phrase:Add,Button,x+15 yp+1 gimport vimport hWndFLBT1,码元管理
	ImageButton.Create(FLBT1, [6, 0x80404040, GuiBgColor<>"4285f4"?0x222222:0x4285f4, 0xffffff], [ , 0x80606060, 0xF0F0F0, GuiBgColor<>"4285f4"?0x111111:0x4285f4],"", [0, 0xC0A0A0A0, , 0xC0e81010])
	Gui,Phrase:Add,Button,x+15 yp gsetfont vsetfont hWndFLBT2,更换字体
	ImageButton.Create(FLBT2, [6, 0x80404040, GuiBgColor<>"4285f4"?0x222222:0x4285f4, 0xffffff], [ , 0x80606060, 0xF0F0F0, GuiBgColor<>"4285f4"?0x111111:0x4285f4],"", [0, 0xC0A0A0A0, , 0xC0e81010])
	Gui,Phrase:Font,s10 ,%DefaultFontName%
	Gui,Phrase:add,edit,x+15 yp w55 Number Limit2 gControlFontSize vControlFontSize cffffff,% FontSize
	Gui,Phrase:Add, UpDown, Range9-32 , % FontSize
	GuiControlGet,cfpos,Phrase:pos,ControlFontSize
	Gui,Phrase:Add,Button,% "x" (posX+85*4+15*3>cfposX+55?posX+85*4+15*3+15:cfposX+55+15) " yp" -cfposH*2 " hWndFLBT3 gSendClipText vSendClipText ",发`n送`n上`n屏
	ImageButton.Create(FLBT3, [6, 0x80404040, GuiBgColor<>"4285f4"?0x222222:0x4285f4, 0xffffff], [ , 0x80606060, 0xF0F0F0, GuiBgColor<>"4285f4"?0x111111:0x4285f4],"", [0, 0xC0A0A0A0, , 0xC0e81010])
	Gui,Phrase:Font,s10 bold cffffff,%DefaultFontName%
	Gui,Phrase:Add,ListBox,% "x" posX " y" (posY+(posH+15)*2) " r1 w120 cwhite gPhraseHotkey vPhraseHotkey 0x100 +BackgroundTrans ReadOnly -Multi hwndSetHotkey",%Hotkeys%
	Gui,Phrase:Font,s10 norm cffffff,%DefaultFontName%
	GuiControlGet,PHkpos,Phrase:pos,PhraseHotkey
	GuiControl,Phrase:Move,next_part_line,% "h" PHkposY+200
	Gui,Phrase:Add,Checkbox,x+25 yp+4 gPasteType vPasteType Checked%PasteType%,
	Gui,Phrase:Add,Checkbox,x+0 yp gIsContinue vIsContinue Checked%IsContinue%,
	Gui,Phrase:Add,Checkbox,x+0 yp gIsCopy vIsCopy Checked%IsCopy%,
	Gui,Phrase:Add,Checkbox,x+0 yp gSaveAll vIsAutoSave Checked%IsAutoSave%,
	Gui,Phrase:Add,Checkbox,x+0 yp gSetFontBold vIsbold Checked%Isbold%,
	Gui,Phrase:Add,Checkbox,x+0 yp gSetToNextLine vToNext Checked%ToNext%,
	Gui,Phrase:Add,Checkbox,x+0 yp gSetAutoScroll vAutoScroll Checked%AutoScroll%,
	Gui,Phrase:Font,s10 cffffff
	Gui,Phrase:Cancel
	Goto GetEtymologyObj
	EmptyMem()
Return
;;==============================================================================================================================
;;==============================================================================================================================
;;==============================================================================================================================

WheelUpSetting:
	MouseGetPos,,ControlID,MID
	if (WinExist("ahk_id " MakePhrase)=MID&&WinExist("ahk_id " MakePhrase)){
		Return
	}else{
		SendInput,{WheelUp}
	}
Return

WheelDownSetting:
	MouseGetPos,,ControlID,MID
	if (WinExist("ahk_id " MakePhrase)=MID&&WinExist("ahk_id " MakePhrase))
		Return
	else
		SendInput,{WheelDown}
Return

InstallFont:
	RegRead, WeaselRoot, HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Rime\Weasel, WeaselRoot
	DllCall("gdi32\EnumFontFamilies","uint",DllCall("GetDC","uint",0),"uint",0,"uint",RegisterCallback("EnumFontFamilies"),"uint",a_FontList:="")
	if (!InStr("|" a_FontList,"|拆分码元字体|")&&!InStr(WeaselRoot,"98"))
		FileCopy,%A_AppData%\RimeToolData\CnCode\UnionRadicalFont.otf,%A_Desktop%\拆分码元字体.otf,1
	if !InStr("|" a_FontList,"|98WB-3|")
		FileCopy,%A_AppData%\RimeToolData\CnCode\98WB-3.otf,%A_Desktop%\98WB-3.otf,1
	if (FileExist(A_AppData "\RimeToolData\CnCode\UnionRadicalFont.otf")&&!InStr("|" a_FontList,"|拆分码元字体|")){
		AddFontResource(A_AppData "\RimeToolData\CnCode\UnionRadicalFont.otf")
		DllCall("gdi32\EnumFontFamilies","uint",DllCall("GetDC","uint",0),"uint",0,"uint",RegisterCallback("EnumFontFamilies"),"uint",a_FontList:="")
	}
	if (FileExist(A_AppData "\RimeToolData\CnCode\98WB-3.otf")&&!InStr("|" a_FontList,"|98WB-3|")){
		AddFontResource(A_AppData "\RimeToolData\CnCode\98WB-3.otf")
		DllCall("gdi32\EnumFontFamilies","uint",DllCall("GetDC","uint",0),"uint",0,"uint",RegisterCallback("EnumFontFamilies"),"uint",a_FontList:="")
	}
	if (!InStr("|" a_FontList,"|" FontName "|")&&InStr("|" a_FontList,"|拆分码元字体|")&&Schema<>"98"){
		FontName:=PhraseIni.Settings["FontName"]:="拆分码元字体",PhraseIni.save()
	}else if (!InStr("|" a_FontList,"|" FontName "|")&&InStr("|" a_FontList,"|98WB-3|")&&Schema="98"){
		FontName:=PhraseIni.Settings["FontName"]:="98WB-3",PhraseIni.save()
	}else if (!InStr("|" a_FontList,"|" FontName "|")&&!InStr("|" a_FontList,"|拆分码元字体|")&&!InStr(WeaselRoot,"98")){
		FileCopy,%A_AppData%\RimeToolData\CnCode\UnionRadicalFont.otf,%A_Desktop%\拆分码元字体.otf,1
		TrayTip,字体错误,字体载入失败，请安装桌面上的 UnionRadicalFont.otf 字体！,,3
	}else if (!InStr("|" a_FontList,"|" FontName "|")&&!InStr("|" a_FontList,"|98WB-3|")){
		FileCopy,%A_AppData%\RimeToolData\CnCode\98WB-3.otf,%A_Desktop%\98WB-3.otf,1
		TrayTip,字体错误,字体载入失败，请安装桌面上的 98WB-3.otf 字体！,,3
	}
Return

SetWindowsHookEx(idHook, lpfn, hMod, dwthreadId) {
	return DllCall("SetWindowsHookEx", Int, idHook, Ptr, lpfn, Ptr, hMod, UInt, dwthreadId)
}
UnhookWindowsHookEx(hhk) {
	return DllCall("UnhookWindowsHookEx", Ptr, hhk)
}
CallNextHookEx(hhk, nCode, wParam, lParam) {
	return DllCall("CallNextHookEx", Ptr, hhk, Int, nCode, Ptr, wParam, Ptr, lParam)
}
GetLastError() {
	return DllCall("GetLastError")
}

CaptainHook(enable := false) {
	global kbhk, mhk, KBCallback, MCallback
	static WH_KEYBOARD := 2, WH_MOUSE := 7
	if(enable) {
		dwThreadId := DllCall("GetCurrentThreadId")

		if(kbhk or mhk) ;remove any old hooks
			CaptainHook(false)

		kbhk := SetWindowsHookEx(WH_KEYBOARD, KBCallback, 0, dwThreadId)
		if(!kbhk)
			MsgBox,262160,错误 ,% "无法设置键盘钩子" . GetLastError()
		mhk := SetWindowsHookEx(WH_MOUSE, MCallback, 0, dwThreadId)
		if(!mhk)
			MsgBox,262160,错误 ,% "无法设置鼠标钩子" . GetLastError()
		;if(mhk and kbhk)
		;	CreateGUI()
	} else {
		if(kbhk) {
			UnhookWindowsHookEx(kbhk)
			kbhk := 0
		}

		if(mhk) {
			UnhookWindowsHookEx(mhk)
			mhk := 0
		}
	}
}

GetArrIndex(obj,var,t=0){
	For key,value in obj
	{
		if (var=value&&t)
			Return key
		else (var=key&&!t)
			Return value
	}
}

KeyboardHookProc(code, wParam, lParam) {
	global MakePhrase,PhraseIni,Hotkeys,versions
	if(code == 0 or code == 3) {
		vk := wParam, sc := lParam, sc:=RegExreplace(Format("{:2X}", sc-1),"[0]{4}$"), vk:=Format("VK{:X}", vk)
		mainKeylist:={LWin:"VK5B", RWin:"VK5C", LShift:"VKA0", RShift:"VKA1", LControl:"VKA2", RControl:"VKA3", LCtrl:"VKA2", RCtrl:"VKA3", LAlt:"VKA4", RAlt:"VKA5",Shift:"VKA1"}
		ControlGetFocus, Control, ahk_id %MakePhrase%
		GuiControlGet, Var, Phrase:Name , %Control%
		If (Var="PhraseHotkey"){
			GuiControl,Phrase:,PhraseHotkey,% "|" (KeyName:=GetKeyName(vk))
			if !ErrorLevel {
				Hotkey,$%Hotkeys%,SendClipText,Off
				Hotkeys:=PhraseIni.Settings["Hotkeys"]:=KeyName,PhraseIni.save()
				Hotkey,$%Hotkeys%,SendClipText,On
				Menu, TRAY,Tip, 拆分扩编助手v%versions%`n - 码表格式：单字+Tab+编码`n - 格式符合要求才会触发选择框`n - 触发键：%Hotkeys%
				CaptainHook(False)
			}
		}
	} else {
		return CallNextHookEx(0, code, wParam, lParam)
	}
}

MouseHookProc(code, wParam, lParam) {
	if(code == 0 or code == 3) {
		m_id := wParam
		mousehookstruct := lParam
		;;tooltip,% Format("VK{:X}", m_id)
	} else {
		return CallNextHookEx(0, code, wParam, lParam)
	}
}

GetTabItemCount(TabHwnd) {
	Return DllCall("SendMessage", "Ptr", TabHwnd, "UInt", 0x1304, "Ptr", 0, "Ptr", 0, "Int")
}

GetEtymologyObj:
	if (FileExist(A_AppData "\RimeToolData\CnCode\EtymologyTable.txt")){
		GetFileBOM(A_AppData "\RimeToolData\CnCode\EtymologyTable.txt", Encoding)
		If Encoding {
			CharsAll:=GetFileContent(A_AppData "\RimeToolData\CnCode\EtymologyTable.txt",Encoding),obj:={}
			if CharsAll~="\n[a-zA-Z]\t[^\x00-\xff]+" {
				Loop,Parse,CharsAll,`n,`r
				{
					if (A_LoopField&&objcount(tarr:=strsplit(A_LoopField,"`t"))) {
						if tarr[1]~="^[a-zA-Z]$"{
							all:=GetCharsPhrase(tarr[1],tarr[2])
							if (objcount(all)=1)
								obj[tarr[1]]:=all[1],result_.=tarr[1] "`t" tarr[2] "`r`n"
							else if (objcount(all)=2){
								obj[tarr[1]]:=all[1],obj[tarr[1] 1]:=all[2],result_.=tarr[1] "`t" tarr[2] "`r`n"
							}
							all:=[]
						}
					}
				}
				if objcount(obj)
					CustomMaBiao:=obj
				CharsAll:="",obj:={}
			}Else
				CharsAll:=""
		}
	}else{
		SchemaList:=DefaultData["Settings","SchemaList"]
		GuiControl,Phrase:,part_5,% "|" DefaultData["Settings","SchemaList"]
		OD_Colors.Attach(HDDL5,{T: 0xFFFFFF, B: Schema=="86"?"0x4285f4":Schema=="98"?"0x665cdd":Schema=="6"?"0x15c23c":"0xcc4f20"})
		GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
	}
	if (objcount(CustomMaBiao)&&!objcount(PhraseObj[Schema])){
		Phraselist:=CustomMaBiao
		GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
	}Else if (!objcount(CustomMaBiao)&&!objcount(PhraseObj[Schema])){
		Schema:=PhraseIni.Settings["Schema"]:=DefaultData["Settings","Schema"]
		,SchemaList:=PhraseIni.Settings["SchemaList"]:=DefaultData["Settings","SchemaList"],PhraseIni.save()
		GuiControl,Phrase:,part_5,% "|" DefaultData["Settings","SchemaList"]
		OD_Colors.Attach(HDDL5,{T: 0xFFFFFF, B: Schema=="86"?"0x4285f4":Schema=="98"?"0x665cdd":Schema=="6"?"0x15c23c":"0xcc4f20"})
		GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
		Phraselist:=PhraseObj[Schema]
		TrayTip,错误提示,自定义码元失效！,,3
	}Else{
		Phraselist:=PhraseObj[Schema]
		GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
	}

Return

ControlFontSize(){
	Global PhraseIni,FontSize,MakePhrase,FontName,Isbold,HDDL1,HDDL2,HDDL3,HDDL4,En_Chr,Phraselist,GuiBgColor
	if WinExist("ahk_id " MakePhrase){
		GuiControlGet,Size,,ControlFontSize,Text
		if Size Between 9 And 32
		{
			FontSize:=PhraseIni.Settings["FontSize"]:=Size,PhraseIni.save()
			Gui, Phrase:Font, % "s" FontSize (Isbold?"bold":"norm"), %FontName%
			Loop,4
			{
				GuiControl, Phrase:Font, part_%A_Index%
			}
		}
	}
}

SetFontBold(){
	Global PhraseIni,FontSize,MakePhrase,FontName,Isbold
	if WinExist("ahk_id " MakePhrase){
		GuiControlGet,bold,,Isbold,Checkbox
		Isbold:=PhraseIni.Settings["Isbold"]:= bold,PhraseIni.save()
		Gui, Phrase:Font, % "s" FontSize (Isbold?"bold":"norm"), %FontName%
		Loop,4
			GuiControl, Phrase:Font, part_%A_Index%
	}
}

SetAutoScroll(){
	Global AutoScroll,PhraseIni
	if A_ThisMenuItemPos
		AutoScroll:=!AutoScroll
	Else
		GuiControlGet,AutoScroll,,AutoScroll,Checkbox
	PhraseIni.Settings["AutoScroll"]:=AutoScroll,PhraseIni.save()
	Menu, Item,ToggleCheck,上屏后自动滚屏
}

SetToNextLine(){
	Global ToNext,PhraseIni
	if A_ThisMenuItemPos
		ToNext:=!ToNext
	Else
		GuiControlGet,ToNext,,ToNext,Checkbox
	PhraseIni.Settings["ToNext"]:=ToNext,PhraseIni.save()
	Menu, Item,ToggleCheck,自动跳过已拆分行
}

PasteType(){
	Global PasteType,PhraseIni,IsPaste
	GuiControlGet,PasteType,,PasteType,Checkbox
	PhraseIni.Settings["PasteType"]:=PasteType,PhraseIni.save()
}
;===================================================================
SetSleepTime(){
	Global SleepTime,PhraseIni
	if A_ThisMenuItemPos {
		Menu, SleepTime,Uncheck,%SleepTime%
		SleepTime:=PhraseIni.Settings["SleepTime"]:=A_ThisMenuItem,PhraseIni.save()
		Menu, SleepTime,Check,%SleepTime%
	}
}

;===================================================================

SaveAll(){
	Global IsAutoSave,PhraseIni
	if A_ThisMenuItemPos
		IsAutoSave:=!IsAutoSave
	Else
		GuiControlGet,IsAutoSave,,IsAutoSave,Checkbox
	PhraseIni.Settings["IsAutoSave"]:=IsAutoSave,PhraseIni.save()
	GuiControl,Phrase:,IsAutoSave,% IsAutoSave
	Menu, Item,ToggleCheck,上屏后自动保存
}

IsCopy(){
	Global IsCopy,PhraseIni,IsPaste
	if A_ThisMenuItemPos
		IsCopy:=!IsCopy
	Else
		GuiControlGet,IsCopy,,IsCopy,Checkbox
	PhraseIni.Settings["IsCopy"]:=IsCopy,PhraseIni.save()
	Menu, Item,ToggleCheck,强制获取光标行
}

IsContinue(){
	Global IsContinue,PhraseIni
	if A_ThisMenuItemPos
		IsContinue:=!IsContinue
	Else
		GuiControlGet,IsContinue,,IsContinue,Checkbox
	PhraseIni.Settings["IsContinue"]:=IsContinue,PhraseIni.save()
	GuiControl,Phrase:,IsContinue,% IsContinue
	Menu, Item,ToggleCheck,连续处理下一行
}

ChangeColor(){
	Global PhraseIni,GuiBgColor,FLBT1,FLBT2,FLBT3
	ControlFocus , Button2
	GuiBgColor:=PhraseIni.Settings["GuiBgColor"]:=GuiBgColor=000000?"4285f4":"000000",PhraseIni.save()
	GuiControl,Phrase:,import,码元管理
	ImageButton.Create(FLBT1, [6, 0x80404040, GuiBgColor<>"4285f4"?0x222222:0x4285f4, 0xffffff], [ , 0x80606060, 0xF0F0F0, GuiBgColor<>"4285f4"?0x111111:0x4285f4],"", [0, 0xC0A0A0A0, , 0xC0e81010])
	GuiControl,Phrase:,import,码元管理
	GuiControl,Phrase:,setfont,更换字体
	ImageButton.Create(FLBT2, [6, 0x80404040, GuiBgColor<>"4285f4"?0x222222:0x4285f4, 0xffffff], [ , 0x80606060, 0xF0F0F0, GuiBgColor<>"4285f4"?0x111111:0x4285f4],"", [0, 0xC0A0A0A0, , 0xC0e81010])
	GuiControl,Phrase:,setfont,更换字体
	GuiControl,Phrase:,SendClipText,发`n送`n上`n屏
	ImageButton.Create(FLBT3, [6, 0x80404040, GuiBgColor<>"4285f4"?0x222222:0x4285f4, 0xffffff], [ , 0x80606060, 0xF0F0F0, GuiBgColor<>"4285f4"?0x111111:0x4285f4],"", [0, 0xC0A0A0A0, , 0xC0e81010])
	GuiControl,Phrase:,SendClipText,发`n送`n上`n屏
	Gui,Phrase:Color,% (GuiBgColor~="i)0x"?SubStr(GuiBgColor,2):GuiBgColor),% (GuiBgColor~="i)0x"?SubStr(GuiBgColor,2):GuiBgColor)
	Loop,4
		OD_Colors.Attach(HDDL%A_Index%,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
}
GetDefaultFontName(){
	NumPut(VarSetCapacity(info, A_IsUnicode ? 504 : 344, 0), info, 0, "UInt")
	DllCall("SystemParametersInfo", "UInt", 0x29, "UInt", 0, "Ptr", &info, "UInt", 0)
	return StrGet(&info + 52)
}

WM_MOUSEMOVE(){
	global FontName,Schema
	static CurRControl, PrevControl
	Tip_Show:={setfont:"当前字体为：〔" FontName "〕",PasteType:"组合结果另起一行上屏",AutoScroll:"上屏后窗口自动滚动"
		,part_5:"当前方案为：" (Schema=="6"?"新世纪五笔":Schema=="86"?"86五笔":Schema=="98"?"98五笔":Schema)
		,import:"导入自定义四码方案码元",IsContinue:"连续处理下一行",IsCopy:"自动获取光标行文字，`nEmEditor编辑器可以不用勾选。"
		,PhraseHotkey:"自定义触发键",IsAutoSave:"勾选拆分上屏后自动保存",ControlFontSize:"码元字号更换" ,Isbold:"码元字体加粗"
		,ToNext:"智能跳过已拆分行"}
	CurRControl := A_GuiControl
	if (CurRControl <> PrevControl and !InStr(CurRControl, A_Space))
	{
		SetTimer, DisplayToolTip, 500
		PrevControl := CurRControl
	}

	DisplayToolTip:
		SetTimer, DisplayToolTip, Off
		ToolTip % Tip_Show[CurRControl]
		SetTimer, RMToolTip, 3000
	return

	RMToolTip:
		SetTimer, RMToolTip, Off
		ToolTip
	return
}

WM_LBUTTONDOWN() {
	PostMessage, 0xA1, 2 
}

PhraseHotkey:
	CaptainHook(True)
Return

Control_set:
	if A_GuiControl {
		if (A_GuiControl="part_5"){
			GuiControlGet,part_5,,%A_GuiControl%,Text
			if (part_5<>"") {
				Phraselist:=objcount(PhraseObj[part_5])?PhraseObj[part_5]:objcount(CustomMaBiao)?CustomMaBiao:Phraselist
				if (objcount(PhraseObj[part_5])||!objcount(PhraseObj[part_5])&&objcount(CustomMaBiao))
					Schema:=PhraseIni.Settings["Schema"]:=part_5,PhraseIni.save()
				GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
				OD_Colors.Attach(HDDL5,{T: 0xFFFFFF, B: Schema=="86"?"0x4285f4":Schema=="98"?"0x665cdd":Schema=="6"?"0x15c23c":"0xcc4f20"})
				if (part_5=86||part_5=98||part_5="06"){
					if (!InStr(FontName,"98WB")&&part_5=98||part_5=86&&FontName<>"拆分码元字体"||part_5="06"&&FontName<>"拆分码元字体"){
						if (!InStr(a_FontList,"拆分码元字体")||!InStr(a_FontList,"98WB-3"))
							Gosub InstallFont
						Else
							FontName:=PhraseIni.Settings["FontName"]:=Schema="98"?"98WB-3":"拆分码元字体",PhraseIni.save()
						Gui, Phrase:Font, s44, %FontName%
						GuiControl, Phrase:Font, tip
						Gui, Phrase:Font, % "s" FontSize (Isbold?"bold":"norm"), %FontName%
						GuiControl, Phrase:Font, part_1
						GuiControl, Phrase:Font, part_2
						GuiControl, Phrase:Font, part_3
						GuiControl, Phrase:Font, part_4
					}
				}
				loop,Parse,En_Chr
				{
					bianma_:=InStr("gfdhjknbvyuitre",A_LoopField)?A_Index=3&&StrLen(En_Chr)=3||A_Index=4&&StrLen(En_Chr)=4?(A_LoopField 1):A_LoopField:A_LoopField
					if Phraselist[bianma_] {
						GuiControl,Phrase:,part_%A_Index%,% "|" Phraselist[bianma_]
						OD_Colors.Attach(HDDL%A_Index%,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
					}
				}
				IsPaste:=0,BreakItem:=0
			}
		}Else{
			IsPaste:=1,BreakItem:=0
		}
	}
Return

setfont(){
	Global FontName,PhraseIni,FontSize,Isbold
	If objCount(fontObject:=FontSelect(fontObject)) {
		FontName:=PhraseIni.Settings["FontName"]:=fontObject["name"],PhraseIni.save()
		Gui, Phrase:Font, s44, %FontName%
		GuiControl, Phrase:Font, tip
		Gui, Phrase:Font, % "s" FontSize (Isbold?"bold":"norm"), %FontName%
		GuiControl, Phrase:Font, part_1
		GuiControl, Phrase:Font, part_2
		GuiControl, Phrase:Font, part_3
		GuiControl, Phrase:Font, part_4
	}
}

SetFullCode(){
	Gui,+OwnDialogs
	FileSelectFile, MaBiaoFile1, 3, , 选择单义拆分码表, Text Documents (*.txt)
	if (MaBiaoFile1<>""){
		result:=""
		if Items1:=GetFileContent(MaBiaoFile1) {
			if Items1~="\n[^\x00-\xff]+\t[^\x00-\xff]+"{
				FileSelectFile, MaBiaoFile2, 3, , 选择单义/多义码表, Text Documents (*.txt)
				if (MaBiaoFile2<>""){
					if Items2:=GetFileContent(MaBiaoFile2) {
						if Not Items2~="\n[^\x00-\xff]+\t[a-zA-z]+"
							Items2:=TransformCiku(Items2)
						if Items2~="\n[^\x00-\xff]+\t[a-zA-z]+" {
							if objcount(obj:=RemovalCode(Items1)){
								totalCount:=CountLines(Items2), num:=Ceil(totalCount/100),Count:=0
								Progress, M1 Y10 FM14 W350, 1/%totalCount%, 码表匹配处理中..., 1`%
								Loop,Parse,Items2,`n,`r
								{
									Count++
									if objcount(tarr:=strsplit(A_LoopField,"`t")){
										if obj[tarr[1]] {
											result.=A_LoopField "`t" RegExReplace(obj[tarr[1]],"\〔|\〕") "`r`n"
										}Else
											result.=A_LoopField "`r`n"
									}
									tx :=Ceil(count/num)
									Progress, %tx% , %count%/%totalCount%`n, 码表匹配处理中..., 已完成%tx%`%
								}
								Progress,off
								if result {
									FileRecycle,Etymology_单义.txt
									FileAppend,%result%,Etymology_单义.txt,UTF-8
									TrayTip,拆分助手,处理完成，导出文件为Etymology_单义.txt！,,1
									OpenAndSelect(A_ScriptDir "\Etymology_单义.txt")
								}
								Items2:=Items1:=result:="",EmptyMem()
							}
						}else
							TrayTip,拆分助手,方案码表非单行单义/单行多义！,,3
						EmptyMem()
					}Else
						TrayTip,拆分助手,方案码表编码格式不支持！,,3
					EmptyMem()

				}
			}Else
				TrayTip,拆分助手,拆分码表格式不支持！,,3
			EmptyMem()
		}
	}
}

EmptyMem(PID=""){
	pid:=!PID ? DllCall("GetCurrentProcessId") : pid
	h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid)
	DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
	DllCall("CloseHandle", "Int", h)
}

GetFullCode(){
	Gui,+OwnDialogs
	FileSelectFile, MaBiaoFile, 3, , 选择单义/多义码表, Text Documents (*.txt)
	if (MaBiaoFile<>""){
		result:=""
		if Items:=GetFileContent(MaBiaoFile) {
			if Not Items~="\n[^\x00-\xff]+\t[a-zA-z]+"
				Items:=TransformCiku(Items)
			if Items {
				if objcount(obj:=RemovalCode(Items)) {
					for key,Value In obj
					{
						result.=key "`t" Value "`r`n"
					}
					if result {
						FileRecycle,FullCode.txt
						FileAppend,%result%,FullCode.txt,UTF-8
						TrayTip,拆分助手,单字去重提取成功，码表为FullCode.txt！,,1
						OpenAndSelect(A_ScriptDir "\FullCode.txt")
					}Else
						TrayTip,拆分助手,提取失败！,,3
				}Else
					TrayTip,拆分助手,提取失败！,,3
			}Else
				TrayTip,拆分助手,码表格式不支持！,,3
			Items:=result:="",obj:={},EmptyMem()
		}
	}
}

OnHelp(){
	Run, http://98wb.ys168.com/,, UseErrorLevel
	if (ErrorLevel = "ERROR") {
		Run, iexplore.exe "98wb.ys168.com/",, UseErrorLevel
	}
}

Onabout(){
	Run, https://gitee.com/leeonchiu/InputMethod-Tools,, UseErrorLevel
	if (ErrorLevel = "ERROR") {
		Run, iexplore.exe "https://gitee.com/leeonchiu/InputMethod-Tools",, UseErrorLevel
	}
}

IsWithBOM(ByRef String){
	if (0xBFBBEF=NumGet(&String,"UInt") & 0xFFFFFF) ;UTF-8
		return "UTF-8"
	else if (0xFEFF=NumGet(&String,"UShort"))  ;UTF-16LE
		return "UTF-16LE"
	else return 0
}

NoBOM(ByRef String){
	if (0xBFBBEF=NumGet(&String,"UInt") & 0xFFFFFF)
		return String:=StrGet(&String+3,"UTF-8")
	else if (0xFFFE=NumGet(&String,"UShort") || 0xFEFF=NumGet(&String,"UShort"))
		return String:=SubStr(&String+2,"UTF-16")
	else return String
}

GetFileBOM(FilePath,ByRef Encoding){
	FileRead,text,*c %FilePath%
	If (0xBFBBEF=NumGet(&text,"UInt") & 0xFFFFFF){
		Encoding:= "UTF-8" 
	}else If (0xFEFF=NumGet(&text,"UShort") ){   ;UTF-16 LE with BOM
		Encoding:= "UTF-16"
	}
}

RestartAll:
	Hotkey,$%Hotkeys%,SendClipText,off
	For Section, element In DefaultData
		For key, value In element
			%key%:=PhraseIni[Section, key]:=value
	init:=PhraseIni.Settings["init"]:=1,PhraseIni.save()
	Hotkey,$%Hotkeys%,SendClipText,On
	Gui, Phrase:Font, s44, %FontName%
	GuiControl, Phrase:Font, tip
	Gui, Phrase:Font, % "s" FontSize (Isbold?"bold":"norm"), %FontName%
	GuiControl, Phrase:Font, part_1
	GuiControl, Phrase:Font, part_2
	GuiControl, Phrase:Font, part_3
	GuiControl, Phrase:Font, part_4
	GuiControl,Phrase:,part_5,% "|" SchemaList
	OD_Colors.Attach(HDDL5,{T: 0xFFFFFF, B: Schema=="86"?"0x4285f4":Schema=="98"?"0x665cdd":Schema=="6"?"0x15c23c":"0xcc4f20"})
	GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
	GuiControl,Phrase:,IsContinue,% IsContinue
	GuiControl,Phrase:,PasteType,% PasteType
	GuiControl,Phrase:,IsCopy,% IsCopy
	GuiControl,Phrase:,PhraseHotkey,% "|" Hotkeys
	loop,Parse,En_Chr
	{
		bianma_:=InStr("gfdhjknbvyuitre",A_LoopField)?A_Index=3&&StrLen(En_Chr)=3||A_Index=4&&StrLen(En_Chr)=4?(A_LoopField 1):A_LoopField:A_LoopField
		if Phraselist[bianma_] {
			GuiControl,Phrase:,part_%A_Index%,% "|" Phraselist[bianma_]
			OD_Colors.Attach(HDDL%A_Index%,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
		}
	}
	Gui,Phrase:Color,% (GuiBgColor~="i)0x"?SubStr(GuiBgColor,2):GuiBgColor),% (GuiBgColor~="i)0x"?SubStr(GuiBgColor,2):GuiBgColor)
	Loop,4
		OD_Colors.Attach(HDDL%A_Index%,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
	IsPaste:=0,BreakItem:=0
	Menu, TRAY,Tip, 拆分扩编助手`n - 码表格式：单字+Tab+编码`n - 格式符合要求才会触发选择框`n - 触发键：%Hotkeys%
	TrayTip,,重置完成！,1
Return

import(){
	Global Phraselist,Schema,PhraseIni,SchemaList,CustomMaBiao,HDDL5,DefaultData,GuiBgColor
		,PhraseObj,FontName,a_FontList,IsPaste,FontName,FontSize,Isbold,En_Chr,BreakItem:=0
	obj:={}
	;GuiControl,Phrase:, +Owner
	Gui,+OwnDialogs
	MsgBoxRenBtn("重置","新增","取消")
	MsgBox, 262659,方案基础码元导入,重置默认王码三方案或导入自定义四码方案`n25/26组码元文件格式：字母+Tab+键位字根
	IfMsgBox,Yes
	{
		SchemaList:=PhraseIni.Settings["SchemaList"]:=DefaultData["Settings","SchemaList"]
		FontName:=PhraseIni.Settings["FontName"]:=DefaultData["Settings","FontName"]
		GuiControl,Phrase:,part_5,% "|" SchemaList
		OD_Colors.Attach(HDDL5,{T: 0xFFFFFF, B: Schema=="86"?"0x4285f4":Schema=="98"?"0x665cdd":Schema=="6"?"0x15c23c":"0xcc4f20"})
		GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
		if !InStr("|" SchemaList "|","|" Schema "|"){
			Schema:=PhraseIni.Settings["Schema"]:=DefaultData["Settings","Schema"],Phraselist:=PhraseObj[Schema]
			loop,Parse,En_Chr
			{
				bianma_:=InStr("gfdhjknbvyuitre",A_LoopField)?A_Index=3&&StrLen(En_Chr)=3||A_Index=4&&StrLen(En_Chr)=4?(A_LoopField 1):A_LoopField:A_LoopField
				if Phraselist[bianma_] {
					GuiControl,Phrase:,part_%A_Index%,% "|" Phraselist[bianma_]
					OD_Colors.Attach(HDDL%A_Index%,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
				}
			}
		}
		PhraseIni.save(),IsPaste:=0,BreakItem:=0
	}
	Else IfMsgBox,No
	{
		if Items:=SetParameterGui("请输入方案名","",, ,1,1,"Phrase"){
			Items:=RegExReplace(Items,"[\n\t\s]")
			if InStr("|" DefaultData["Settings","SchemaList"] "|","|" Items "|"){
				TrayTip,命名错误,「%Items%」已存在，不能重复命名！,,3
				Return
			}else{
				Gui,+OwnDialogs
				FileSelectFile, MaBiaoFile, 3, %A_AppData%\RimeToolData\CnCode\, 导入25/26组拆分码元表, Text Documents (*.txt)
				if (MaBiaoFile<>""){
					GetFileBOM(MaBiaoFile, Encoding)
					If Encoding {
						CharsAll:=GetFileContent(MaBiaoFile,Encoding),result_:=""
						if CharsAll~="\n[a-zA-Z]\t[^\x00-\xff]+" {
							Loop,Parse,CharsAll,`n,`r
							{
								if (A_LoopField&&objcount(tarr:=strsplit(A_LoopField,"`t"))) {
									if tarr[1]~="^[a-zA-Z]$"{
										all:=GetCharsPhrase(tarr[1],tarr[2])
										if (objcount(all)=1)
											obj[tarr[1]]:=all[1],result_.=tarr[1] "`t" tarr[2] "`r`n"
										else if (objcount(all)=2){
											obj[tarr[1]]:=all[1],obj[tarr[1] 1]:=all[2],result_.=tarr[1] "`t" tarr[2] "`r`n"
										}
									}
								}
							}
							if objcount(all)
								TrayTip,码元导入,拆分码元导入成功！,,1
							if objcount(obj){
								CustomMaBiao:=obj,Phraselist:=obj,Schema:=PhraseIni.Settings["Schema"]:=Items,PhraseIni.save()
								if (objcount(strsplit(SchemaList,"|"))>3){
									SchemaList:=PhraseIni.Settings["SchemaList"]:=DefaultData["Settings","SchemaList"] "|" Items,PhraseIni.save()
								}Else
									SchemaList:=PhraseIni.Settings["SchemaList"]:=SchemaList "|" Items,PhraseIni.save()
								GuiControl,Phrase:,part_5,% "|" SchemaList
								OD_Colors.Attach(HDDL5,{T: 0xFFFFFF, B: Schema=="86"?"0x4285f4":Schema=="98"?"0x665cdd":Schema=="6"?"0x15c23c":"0xcc4f20"})
								GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
								if not Schema~="^(6|86|98)$"{
									loop,Parse,En_Chr
									{
										bianma_:=InStr("gfdhjknbvyuitre",A_LoopField)?A_Index=3&&StrLen(En_Chr)=3||A_Index=4&&StrLen(En_Chr)=4?(A_LoopField 1):A_LoopField:A_LoopField
										if Phraselist[bianma_] {
											GuiControl,Phrase:,part_%A_Index%,% "|" Phraselist[bianma_]
											OD_Colors.Attach(HDDL%A_Index%,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
										}
									}
									IsPaste:=0,BreakItem:=0
								}
								FileRecycle,%A_AppData%\RimeToolData\CnCode\EtymologyTable.txt
								FileAppend,%result_%,%A_AppData%\RimeToolData\CnCode\EtymologyTable.txt,UTF-8
							}
							CharsAll:="",result_:="",obj:={}
						}Else{
							CharsAll:="",result_:=""
							TrayTip,格式出错,文件格式不正确，正确格式：[a-z]+Tab+码元!,,3
						}
					}Else
						TrayTip,编码出错,文件编码非UTF-8 with BOM或UTF-16 LE with BOM!,,3
				}
			}

		}Else{
			GuiControl,Phrase:Choose,part_5,% (Schema==86?1:Schema==98?2:Schema=6?3:4)
		}
	}
}

MsgBoxRenBtn(btn1="",btn2="",btn3=""){
	Static sbtn1:="", sbtn2:="", sbtn3:="", i=0
	sbtn1 := btn1, sbtn2 := btn2, sbtn3 := btn3, i=0
	SetTimer, MsgBoxRenBtn, 1
	Return

	MsgBoxRenBtn:
		If (hwnd:=WinActive("ahk_class #32770")) {
			if (sbtn1)
				ControlSetText, Button1, % sbtn1, ahk_id %hwnd%
			if (sbtn2)
				ControlSetText, Button2, % sbtn2, ahk_id %hwnd%
			if (sbtn3)
				ControlSetText, Button3, % sbtn3, ahk_id %hwnd%
			SetTimer, MsgBoxRenBtn, Off
		}
		if (i >= 1000)
			SetTimer, MsgBoxRenBtn, Off
		i++
	Return
}

OnReload(){
	RemoveFontResource(A_AppData "\RimeToolData\CnCode\98WB-3.otf")
	RemoveFontResource(A_AppData "\RimeToolData\CnCode\UnionRadicalFont.otf")
	Reload
}

OnExit(){
	RemoveFontResource(A_AppData "\RimeToolData\CnCode\98WB-3.otf")
	RemoveFontResource(A_AppData "\RimeToolData\CnCode\UnionRadicalFont.otf")
	ExitApp
}

SplitCharstoObj(chars){
	if (chars="")
		Return
	obj:={}, index:=1
	While index:=RegExMatch(chars, "O).", match, index)
	{
		if match.Value
			ObjPush(obj,match.Value) , index+=match.Len
	}
	return obj
}

GetCharsPhrase(var,chars){
	Local match,str_,str
	str:="", index:=1
	if (RegExMatch(chars,"󰀌|󰀘|󰀝|󰀢|󰀬|󰀵|󰀏|󰁣|󰁥|󰁶|󰁧|󰀦|󰁀|󰀅|󰁫",match_)&&InStr("gfdhjknbvyuitre",var))
		chars:=RegExReplace(chars,match_),str_:=""
	While index:=RegExMatch(chars, "O).", match, index)
	{
		if (A_Index=3&&match_)
			str_:=str match_ "|"
		str.=match.Value (index=1?"||":"|")
		if str_
			str_.=match.Value (index=1?"||":"|")
		index+=match.Len
	}
	return match_?[str match_,RegExReplace(str_,"\|$")]:[RegExReplace(str,"\|$")]
}

SetParameterGui(Title:="InputBox",TipText:="", IsNumber=0, Width:=250,Row=0,NoOwner=1,Owner:=""){
	static
	ButtonOK:=ButtonCancel:= false,IsNumber:=IsNumber=1?"Number":"",O:=NoOwner?"+Owner -SysMenu":""
	,flag:=0,wpos:=0,hpos:=0,SetRow:=Row?"R" Row:" Multi "
	Gui, InputBox:Destroy
	If Owner
		Gui, InputBox:+Owner%Owner%
	Gui, InputBox: %O% +AlwaysOnTop -DPIScale +Resize -MaximizeBox +LastFound -MinimizeBox hWndsInputBox
	Gui, InputBox:Font,s10, 
	Gui, InputBox: add, Edit,x15 y15 %SetRow% w%Width% %IsNumber% vInputBox hwndIBox WantTab,% Row>1?TipText:""
	If (Row=1)
		EM_SetCueBanner(IBox, TipText)
	Gui, InputBox:Font,s10 bold,
	Gui, InputBox: add, Button, w60 gInputBoxOK vInputBoxOK , &确定
	GuiControlGet, ibox, Pos , InputBoxOK
	xpos:=Width-45
	Gui, InputBox: add, Button, w60 x%xpos% yp gInputBoxCancel, &取消
	;;GuiControl,InputBox:,InputBox,
	Gui, InputBox: Add,StatusBar,0x100
	Gui, InputBox: Show,AutoSize, % Title
	if !NoOwner
		Gui, InputBox: -AlwaysOnTop
	SendMessage, 0xB1, 0, -1, Edit1, A
	ControlFocus , Edit1, A
	while !(ButtonOK||ButtonCancel)
		continue
	if ButtonCancel {
		return
	}
	Gui, InputBox: Submit, NoHide
	Gui, InputBox: Cancel
	Gui, InputBox:Destroy
	flag:=0
	return InputBox

	InputBoxOK:
		ButtonOK:= true
	return

	InputBoxGuiSize:
		If !flag {
			flag:=1
			Gui, InputBox:+MinSize%A_GuiWidth%x%A_GuiHeight%
		}else{
			ControlGetPos , X_Edit, Y_Edit, Width, Height, Edit1
			GuiControl, InputBox:move, Edit1 , % "w" Width+A_GuiWidth-wpos "h" Height+A_GuiHeight-hpos
			ControlGetPos , X_button, Y_button, w_button, h_button, Button2
			ControlGetPos , X_Edit2, Y_Edit2, Width, Height, Edit1
			GuiControl, InputBox:move, Button1 , % "y" Height+25 
			GuiControl, InputBox:move, Button2 , % "y" Height+25 "x" Width+X_Edit2-w_button-8
		}
		wpos:= A_GuiWidth ,hpos:= A_GuiHeight
	return

	InputBoxGuiClose:
	InputBoxGuiEscape:
		InputBoxCancel:
		ButtonCancel:= true,flag:=0
		Gui, InputBox: Cancel
		Gui, InputBox:Destroy
	return
}

~Esc::
	BreakItem:=1
	debug("*********触发Esc键*********`n当前活动窗口句柄：" CFID "`n中断参数设置为：" BreakItem)
	DetectHiddenWindows, On
	if WinExist("ahk_id " MakePhrase){
		DetectHiddenWindows, Off
		IsPaste:=0,BreakItem:=0
		Goto ShowGui
		EmptyMem()
	}
	DetectHiddenWindows, Off
Return

PhraseGuiClose:
	IsPaste:=0,BreakItem:=0
	Gui,Phrase:Cancel
Return

EM_SetCueBanner(hWnd, Cue)
{
	static EM_SETCUEBANNER := 0x1501
	return DllCall("User32.dll\SendMessage", "Ptr", hWnd, "UInt", EM_SETCUEBANNER, "Ptr", True, "WStr", Cue)
}

GetObjContents(arr,delimiter:="",info="",t=0,list=1){   ;双重数组时t=1，list为双重数组第几位
	if !objcount(arr)
		Return
	if t {
		chars:=""
		for Section,element in arr
			chars.=element[list] info delimiter
	}else{
		chars:=""
		for key,value in arr
			chars.=value info delimiter
	}
	Return RegExReplace(chars,delimiter "$")
}

GetCaretPos(Byacc:=1){
	Static init
	If (A_CaretX=""){
		Caretx:=Carety:=CaretH:=CaretW:=0
		If (Byacc){
			If (!init)
				init:=DllCall("LoadLibrary","Str","oleacc","Ptr")
			VarSetCapacity(IID,16), idObject:=OBJID_CARET:=0xFFFFFFF8
			, NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0, IID, "Int64")
			, NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81, IID, 8, "Int64")
			If (DllCall("oleacc\AccessibleObjectFromWindow", "Ptr",Hwnd:=WinExist("A"), "UInt",idObject, "Ptr",&IID, "Ptr*",pacc)=0){
				Acc:=ComObject(9,pacc,1), ObjAddRef(pacc)
				Try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId:=0)
				, CaretX:=NumGet(x,0,"int"), CaretY:=NumGet(y,0,"int"), CaretH:=NumGet(h,0,"int")
			}
		}
		If (Caretx=0&&Carety=0){
			MouseGetPos, x, y
			Return {x:x,y:y,h:35,t:"Mouse",Hwnd:Hwnd}
		} Else
			Return {x:Caretx,y:Carety,h:Max(Careth,35),t:"Acc",Hwnd:Hwnd}
	} Else
		Return {x:A_CaretX,y:A_CaretY,h:35,t:"Caret",Hwnd:Hwnd}
}

/*
IsCopy--强制获取光标行
IsAutoSave--上屏后自动保存
IsContinue--连续处理下一行
AutoScroll--上屏后自动滚屏
PasteType--组合结果另起一行上屏
*/
SendClipText:
	DetectHiddenWindows, Off
	if WinExist("ahk_id " MakePhrase){
		if IsPaste
			Gui,Phrase:Submit
		WinActivate , ahk_id %CFID%
		ControlFocus , control
		if (part_1&&IsPaste||part_2&&IsPaste||part_3&&IsPaste||part_4&&IsPaste){
			if (Abs(EndNormal-StartNormal)&&EndNormal&&!PasteType){
				parts:=part_1 part_2 part_3 part_4
				PartChars:=!IsCopy?(tip A_Tab En_Chr A_Tab parts): A_Tab parts
			}else if (Abs(EndNormal-StartNormal)&&EndNormal&&PasteType||EndNormal=StartNormal&&EndNormal&&PasteType){
				parts:=part_1 part_2 part_3 part_4,PartChars:="`r`n" tip A_Tab En_Chr A_Tab parts
			}Else
				parts:=part_1 part_2 part_3 part_4,PartChars:=A_Tab parts
			If WinClipFunc(PartChars,1){
				loop,4
				{
					GuiControl,Phrase:,part_%A_Index%,|
					OD_Colors.Attach(HDDL%A_Index%,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
				}
				if IsAutoSave {
					SendInput, ^{vk53sc01F}
				}
				if AutoScroll {
					SendInput,{WheelDown}
				}
				SendInput,{End}{Down}{End}
			}Else
				TrayTip,上屏错误,字符处理异常，上屏失败！,,3
		}
		if IsContinue {
			if (ActiveID:=WinActive("A"))
				CFID:=ActiveID
			debug("*********持续载入下一行*********`n当前活动窗口句柄：" CFID)
			IsPaste:=0,BreakItem:=0
			Goto GetCaretText
		}Else{
			Gui,Phrase:Cancel
		}
		IsPaste:=0,BreakItem:=0
	}else{
		IsPaste:=0
		debug("*********触发键按下后窗口不存在*********`n当前活动窗口句柄：" CFID)
		Goto GetCaretText
	}
Return

GetFileSize(File,Units:="K"){
	FileGetSize, OutputVar , %File%, %Units%
	return OutputVar
}

debug(text,t=0){
	if (t||GetFileSize(A_AppData "\RimeToolData\debug.log")>500)
		FileDelete,%A_AppData%\RimeToolData\debug.Log
	FileAppend,%text%`n记录时间：%A_MM%-%A_DD% %A_HOUR%:%A_MIN% %A_SEC%`n,%A_AppData%\RimeToolData\debug.Log,UTF-8
}

WinClipFunc(value:="",Paste:=0){  ;Paste-->0&&value置空：重复,Paste-->1&&value赋值：粘贴
	Global SleepTime
	if !Clipboard {
		Clipboard:="   "
		Sleep,%SleepTime%
	}
	WinClip.Snap( ClipSaved )
	Sleep,%SleepTime%
	WinClip.Clear()
	if !Paste {
		WinClip.Copy()
		Sleep,%SleepTime%
		Chars:=WinClip.GetText()
		WinClip.Restore( ClipSaved )
		Return Chars
	}else{
		WinClip.SetText(value)
		WinClip.Paste()
		WinClip.Restore( ClipSaved )
		Return 1
	}
}

GetCaretText:
	if A_PriorKey~="(Esc|LButton)"{
		BreakItem:=0
		debug("`n*********捕获上次触发Esc中断参数重置*********`n当前活动窗口句柄：" CFID "`n中断参数：" BreakItem )
	}
	debug("`n*********开始获取光标行*********`n当前活动窗口句柄：" CFID "`n上次触发的热键：" RegExReplace(A_PriorKey,"\~|\$") )
	StartNormal := 0,EndNormal := 0
	GetSelectionNormal(GetControl(WinActive("ahk_id " CFID)?CFID:WinActive("A")), StartNormal, EndNormal)
	debug("*********光标行位置已获取*********`n当前活动窗口句柄：" CFID "`n光标起始位置：" StartNormal "`n光标选择结束位置：" EndNormal "-" )
	if (StartNormal&&EndNormal){
		SysGet, _height, 14
		if (StartNormal=EndNormal){
			if (IsCopy||EndNormal<>StartNormal){
				SendInput, {Home}{Shift Down}{End}{Shift Up}
			}
		}
		If FocusText:=WinClipFunc(){
			SendInput, {End}
			RegExMatch(FocusText,"[^\x00-\xff]+\t[a-zA-Z]{1,4}",match),result:=""
			if (match){
				if (FocusText~="[^\x00-\xff]+\t[a-zA-Z]{1,4}\t[^\w]+"&&ToNext){
					debug("*********自动滚动持续*********`n当前活动窗口句柄：" CFID "`n中断参数：" BreakItem)
					if !BreakItem {
						if AutoScroll {
							SendInput,{WheelDown}
						}
						SendInput,{End}{Down}{End}
						IsPaste:=0
						Goto GetCaretText
						Return
					}Else{
						debug("*********自动滚动结束*********`n当前活动窗口句柄：" CFID "`n中断参数：" BreakItem)
						BreakItem:=0
						Return
					}
				}
				tarr:=strsplit(match,"`t"),En_Chr:=tarr[2],tip:=tarr[1]
				GuiControl,Phrase:,tip,% tip
				GuiControl,Phrase:,bianma, %En_Chr% 
				StringLower, En_Chr, En_Chr
				loop,Parse,En_Chr
				{
					bianma_:=InStr("gfdhjknbvyuitre",A_LoopField)?A_Index=3&&StrLen(En_Chr)=3||A_Index=4&&StrLen(En_Chr)=4?(A_LoopField 1):A_LoopField:A_LoopField
					if Phraselist[bianma_] {
						GuiControl,Phrase:,part_%A_Index%,% "|" Phraselist[bianma_]
						OD_Colors.Attach(HDDL%A_Index%,{T: 0xFFFFFF, B:GuiBgColor~="i)0x"?GuiBgColor:"0x" GuiBgColor})
					}
				}
				if (StrLen(En_Chr)=1){
					GuiControl,Phrase:Enable,part_1
					GuiControl,Phrase:Disable,part_2
					GuiControl,Phrase:,part_2,|
					GuiControl,Phrase:Disable,part_3
					GuiControl,Phrase:,part_3,|
					GuiControl,Phrase:Disable,part_4
					GuiControl,Phrase:,part_4,|
				}else if (StrLen(En_Chr)=2){
					GuiControl,Phrase:Enable,part_1
					GuiControl,Phrase:Enable,part_2
					GuiControl,Phrase:Disable,part_3
					GuiControl,Phrase:,part_3,|
					GuiControl,Phrase:Disable,part_4
					GuiControl,Phrase:,part_4,|
				}else if (StrLen(En_Chr)=3){
					GuiControl,Phrase:Enable,part_1
					GuiControl,Phrase:Enable,part_2
					GuiControl,Phrase:Enable,part_3
					GuiControl,Phrase:Disable,part_4
					GuiControl,Phrase:,part_4,|
				}else if (StrLen(En_Chr)=4){
					GuiControl,Phrase:Enable,part_1
					GuiControl,Phrase:Enable,part_2
					GuiControl,Phrase:Enable,part_3
					GuiControl,Phrase:Enable,part_4
				}
				CFID:=WinActive("A")
				CaretPos:=GetCaretPos()
				if (Height_Pos&&CaretPos.y+Height_Pos+50+Shell_Wnd>A_ScreenHeight){
					if MPID:=WinExist("ahk_id " MakePhrase){
						WinGetTitle, MTitle,ahk_id %MakePhrase%
						WinMove,%MTitle%,, % CaretPos.x, % CaretPos.y-Height_Pos-_height
					}else{
						Gui,Phrase:Show,% "x" CaretPos.x " y" CaretPos.y-Height_Pos-_height " NA",% "   "
					}
				}Else{
					if MPID:=WinExist("ahk_id " MakePhrase){
						WinGetTitle, MTitle,ahk_id %MakePhrase%
						WinMove,%MTitle%,, % CaretPos.x+15, % CaretPos.y+_height
					}else{
						Gui,Phrase:Show,% "x" CaretPos.x+15 " y" CaretPos.y+_height " NA",% "   "
					}
				}
				if (!Height_Pos&&!Height_Pos){
					DetectHiddenWindows, On
					WinGetPos, X_Pos, Y_Pos, Width_Pos, Height_Pos, ahk_id %MakePhrase%
					DetectHiddenWindows, Off
				}
			}Else{
				IsPaste:=0,BreakItem:=0
				Gui,Phrase:Cancel
			}
		}Else{
			debug("*********光标行内容获取失败*********`n当前活动窗口句柄：" CFID "`n光标起始位置： " StartNormal "`n光标结束位置：" EndNormal)
			BreakItem:=0,IsPaste:=0
			TrayTip,获取错误,光标行内容获取失败！,,3
		}
	}Else{
		debug("*********光标行位置获取异常*********`n当前活动窗口句柄：" CFID "`n光标起始位置：" StartNormal "`n光标结束位置：" EndNormal)
		IsPaste:=0,BreakItem:=0
		DetectHiddenWindows, On
		if !WinExist("ahk_id " MakePhrase){
			DetectHiddenWindows, Off
			Goto ShowGui
		}
		DetectHiddenWindows, Off
	}
Return

GetControl(id) {
	Global MCtlClass
	ControlGetFocus, ctrlClass, ahk_id %id%
	MCtlClass:=ctrlClass?ctrlClass:MCtlClass
	ControlGet, ctrlHwnd, Hwnd,, %MCtlClass%,ahk_id %id%
	debug("******" MCtlClass "控件Class获取******`n WinClass：" MCtlClass "`n窗口句柄：" id " `n控件HWND：" ctrlHwnd)
	return ctrlHwnd
}

GetSelectionNormal(ctrl, ByRef start, ByRef end) {
	if !Ctrl {
		start :=0,end :=0
		Return
	}
	SendMessage, EM_GETSEL:=0x00B0, &start, &end,, ahk_id %ctrl%
	start := NumGet(start, 0, "UInt")
	end := NumGet(end, 0, "UInt")
}

; ======================================================================================================================
; Gets the starting and ending character positions of the current selection in an edit control.
; Start  -  receives the start of the current selection
; End    -  receives the end of the current selection
; ======================================================================================================================
EM_GETSEL(HWND, ByRef Start, ByRef End) {
	; EM_GETSEL = 0x00B0 -> msdn.microsoft.com/en-us/library/bb761598(v=vs.85).aspx
	Start := End := 0
	DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", 0x00B0, "UIntP", Start, "UIntP", End, "Ptr")
	++Start, ++End
	Return True
}
; ======================================================================================================================
; Selects a range of characters in an edit control.
; Start  -  the character index of the start of the selection.
; End    -  the character index of the end of the selection.
; ======================================================================================================================
EM_SETSEL(HWND, Start, End) {
	; EM_SETSEL = 0x00B1 -> msdn.microsoft.com/en-us/library/bb761661(v=vs.85).aspx
	Return DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", 0x00B1, "Ptr", Start - 1, "Ptr", End - 1, "Ptr")
}


SB_GetPos(hwnd, Which:="V"){
	Which := (Which="V" || Which=1) ? 1 : (Which="H" || Which=0) ? 0 : 1
	Return DllCall("GetScrollPos", "UInt", Hwnd, "Int", Which)                
}

SB_SetPos(hwnd, Which:="V", To:="0"){
	Which := (Which="V" || Which=1) ? 1 : (Which="H" || Which=0) ? 0 : 1
	Return DllCall("SetScrollPos", "UInt", Hwnd, "Int", Which, "Int", To, "UInt", 1)
}


SetScrollPos(hwnd, fnBar, nPos)
{
	VarSetCapacity(si, 28, 0) ; SCROLLINFO si
	NumPut(28  , si,  0)    ; si.cbSize := sizeof(SCROLLINFO)
	NumPut(0x4 , si,  4)    ; si.fMask := SIF_POS
	NumPut(nPos, si, 20)    ; si.nPos := nPos

	; Use SetScrollInfo first because it supports 32-bit positions.
	; If an application supports positions < 0 or > 65535, it most likely
	; ignores WM_#SCROLL's wParam and uses GetScrollPos or GetScrollInfo
	; to get the actual scroll position.
	DllCall("SetScrollInfo", "uint", hwnd, "int", fnBar, "uint", &si, "int", 0)

	; WM_HSCROLL or WM_VSCROLL must be sent for the window to update it's contents.
	msg := (fnBar=0) ? 0x114 : 0x115
	wParam := 4 ; SB_THUMBPOSITION
	| ((nPos&0xFFFF)<<16)
	SendMessage, msg, wParam,,, ahk_id %hwnd%
	
	return (ErrorLevel != "FAIL")
}

GetScrollInfo(hwnd, fnBar, ByRef nPos=0, ByRef nTrackPos=0, ByRef nMin=0, ByRef nMax=0, ByRef nPage=0)
{
	WinGet, Style, Style, ahk_id %hwnd%
	if !(Style & (fnBar ? 0x200000 : 0x100000))
		return false ; Fix for some controls which report {min:0,max:100} even though scroll bar doesn't exist.

	VarSetCapacity(si, 28, 0) ; SCROLLINFO si
	NumPut(28  , si, 0) ; si.cbSize := sizeof(SCROLLINFO)
	NumPut(0x17, si, 4) ; si.fMask := SIF_ALL

	if ! DllCall("GetScrollInfo", "uint", hwnd, "int", fnBar, "uint", &si)
		return false

	nPos        := NumGet(si, 20)
	nTrackPos   := NumGet(si, 24)
	nMin        := NumGet(si,  8)
	nMax        := NumGet(si, 12)
	nPage       := NumGet(si, 16)
	return true
}

GetFileContent(FilePath,Encoding="UTF-8"){
	If FileExist(FilePath){
		FileEncoding,%Encoding%
		FileRead,chars,%FilePath%
		chars:=RegExReplace(RegExReplace(RegExReplace(chars,"`r`n","`r"),"`n","`r"),"`r","`r`n")
		return RegExReplace(chars,"`r`n[\s\t]+`r`n","`r`n")
	}
}

FontSelect(fontObject:="",hwnd:=0,effects:=1) {
	fontObject := (fontObject="") ? Object() : fontObject
	VarSetCapacity(logfont,60)
	uintVal := DllCall("GetDC","uint",0)
	LogPixels := DllCall("GetDeviceCaps","uint",uintVal,"uint",90)
	Effects := 0x041 + (Effects ? 0x100 : 0)
	
	fntName := fontObject.HasKey("name") ? fontObject["name"] : ""
	fontBold := fontObject.HasKey("bold") ? fontObject["bold"] : 0
	fontBold := fontBold ? 700 : 400
	fontItalic := fontObject.HasKey("italic") ? fontObject["italic"] : 0
	fontUnderline := fontObject.HasKey("underline") ? fontObject["underline"] : 0
	fontStrikeout := fontObject.HasKey("strike") ? fontObject["strike"] : 0
	fontSize := fontObject.HasKey("size") ? fontObject["size"] : 10
	fontSize := fontSize ? Floor(fontSize*LogPixels/72) : 16
	c := fontObject.HasKey("color") ? fontObject["color"] : 0
	
	c1 := Format("0x{:02X}",(c&255)<<16)	; convert RGB colors to BGR for input
	c2 := Format("0x{:02X}",c&65280)
	c3 := Format("0x{:02X}",c>>16)
	fontColor := Format("0x{:06X}",c1|c2|c3)
	
	fontval := Object(16,fontBold,20,fontItalic,21,fontUnderline,22,fontStrikeout,0,fontSize)
	
	for a,b in fontval
		NumPut(b,logfont,a)
	
	cap:=VarSetCapacity(choosefont,A_PtrSize=8?103:60,0)
	NumPut(hwnd,choosefont,A_PtrSize)
	offset1 := (A_PtrSize = 8) ? 24 : 12
	offset2 := (A_PtrSize = 8) ? 36 : 20
	offset3 := (A_PtrSize = 4) ? 6 * A_PtrSize : 5 * A_PtrSize
	
	fontArray := Array([cap,0,"Uint"],[&logfont,offset1,"Uptr"],[effects,offset2,"Uint"],[fontColor,offset3,"Uint"])
	
	for index,value in fontArray
		NumPut(value[1],choosefont,value[2],value[3])
	
	if (A_PtrSize=8) {
		strput(fntName,&logfont+28)
		r := DllCall("comdlg32\ChooseFont","uptr",&CHOOSEFONT,"cdecl")
		fntName := strget(&logfont+28)
	} else {
		strput(fntName,&logfont+28,32,"CP936")
		r := DllCall("comdlg32\ChooseFontA","uptr",&CHOOSEFONT,"cdecl")
		fntName := strget(&logfont+28,32,"CP936")
	}
	
	if !r
		return false
	
	fontObj := Object("bold",16,"italic",20,"underline",21,"strike",22)
	for a,b in fontObj
		fontObject[a] := NumGet(logfont,b,"UChar")
	
	fontObject["bold"] := (fontObject["bold"] < 188) ? 0 : 1
	
	c := NumGet(choosefont,A_PtrSize=4?6*A_PtrSize:5*A_PtrSize) ; convert from BGR to RBG for output
	c1 := Format("0x{:02X}",(c&255)<<16)
	c2 := Format("0x{:02X}",c&65280)
	c3 := Format("0x{:02X}",c>>16)
	c := Format("0x{:06X}",c1|c2|c3)
	fontObject["color"] := c
	
	fontObject["size"] := NumGet(choosefont,A_PtrSize=8?32:16,"UInt")//10
	fontHwnd := DllCall("CreateFontIndirect","uptr",&logfont) ; last param "cdecl"
	fontObject["name"] := fntName
	
	If (!fontHwnd) {
		fontObject := ""
		return 0
	} Else {
		fontObject["hwnd"] := fontHwnd
		b := fontObject["bold"] ? "bold" : ""
		i := fontObject["italic"] ? "italic" : ""
		s := fontObject["strike"] ? "strike" : ""
		c := fontObject["color"] ? "c" fontObject["color"] : ""
		z := fontObject["size"] ? "s" fontObject["size"] : ""
		u := fontObject["underline"] ? "underline" : ""
		fullStr := b "|" i "|" s "|" c "|" z "|" u
		Loop Parse, fullStr, |
			If (A_LoopField) 
				str .= A_LoopField " "
		fontObject["str"] := "norm " Trim(str)
		
		return fontObject
	}
}

;;单行多义格式转换为单行单义
TransformCiku(Chars){
	If (Chars="")
		return ""
	If Chars~="[a-zA-Z]\s.+\s.+" {
		Progress, M ZH-1 ZW-1 Y100 FM12 C0 FM14 WS700 ,, 单行多义格式转换为单行单义中。。。！, 转换提示
		Loop,parse,Chars,`n,`r
		{
			If A_LoopField
			{
				consistent_part:=StrSplit(RegExReplace(A_LoopField,"\s+",A_space),A_space)
				loopvalue_:=consistent_part[1]
				For key,value in consistent_part
					If (key>1&&value)
						loopvalue.=value A_tab loopvalue_ "`r`n"
			}
		}
		Progress,off
		return loopvalue
	}else{
		return ""
	}
}

;;码表单字去重保留全码
RemovalCode(Chars){
	If (Chars="")
		return
	arr:={}, count:=0
	totalCount:=CountLines(Chars), num:=Ceil(totalCount/100)
	Progress, M1 Y10 FM14 W350, 1/%totalCount%, 码表单字去重保留全码处理中..., 1`%
	Loop, Parse, Chars, `n, `r
	{
		tarr:=StrSplit(A_LoopField,A_Tab,A_Tab),count++
		If (objcount(SplitCharstoObj(tarr[1]))=1){
			If (arr[tarr[1]]&&StrLen(tarr[2])>StrLen(arr[tarr[1]])||!arr[tarr[1]])
				arr[tarr[1]]:=tarr[2]
			else
				Continue
		}
		If (Mod(count, num)=0) {
			tx :=Ceil(count/num)
			Progress, %tx% , %count%/%totalCount%`n, 码表单字去重保留全码处理中..., 已完成%tx%`%
		}
	}
	Progress,off
	return arr
}

;;统计行数
CountLines(file){ 
	If not file~="`n"
		FileRead, Text, %file%
	else
		Text:=file
	StringReplace, Text, Text, `n, `n, UseErrorLevel
	Text:=""
	Return ErrorLevel + 1
}

AddFontResource(FontPath){
	If FileExist(FontPath){
		DllCall("GDI32.DLL\AddFontResource", str, FontPath)
		PostMessage, 0x1D,,,, ahk_id 0xFFFF
		return 1
	}
}

RemoveFontResource(FontPath){
	DllCall("GDI32.DLL\RemoveFontResource", Str, FontPath)
	PostMessage, 0x1D,,,, ahk_id 0xFFFF
}

EnumFontFamilies(lpelf,lpntm,lP)
{
	global a_FontList
	if (substr(StrGet(lpelf+28),1,1)<>"@")
		a_FontList .= StrGet(lpelf+28) . "|" 
	Return 1
}

OpenAndSelect(sFullPath){
	SplitPath sFullPath, , sPath, ext, name_no_ext
	FolderPidl := DllCall("shell32\ILCreateFromPath", "Str", sPath)
	DllCall("shell32\SHParseDisplayName", "str", sFullPath, "Ptr", 0, "Ptr*", ItemPidl := 0, "Uint", 0, "Uint*", 0)
	DllCall("shell32\SHOpenFolderAndSelectItems", "Ptr", FolderPidl, "UInt", 1, "Ptr*", ItemPidl, "Int", 0)
	CoTaskMemFree(FolderPidl)
	if name_no_ext
		CoTaskMemFree(ItemPidl)
}

CoTaskMemFree(pv) {
	Return DllCall("ole32\CoTaskMemFree", "Ptr", pv)
}